﻿using MQTTnet;
using MQTTnet.Client;
using System;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SiriRobot
{
    public partial class FrmMain : Form
    {
        string _firstShowClientId = "********************************";

        public FrmMain()
        {
            InitializeComponent();
            InitializeConfig();

            lblClientId.Text = _firstShowClientId;

        }

        IMqttClient _mqttClient;
        MqttClientOptions _mqttClientOptions;
        MqttFactory _mqttFactory;
        Config _config;
        MqttClientSubscribeOptions _mqttClientSubscribeOptions;
        private void FrmMain_LoadAsync(object sender, EventArgs e)
        {
            _config = EasyConf.Read<Config>();
            RegistryHelper.AutoRun(_config.AutoRun);
            PluginLoader.LoadPlugins(App.PluginDirectoryPath);
            lblPluginCount.Text = PluginLoader.Plugins.Count().ToString();

            _mqttFactory = new MqttFactory();
            _mqttClient = _mqttFactory.CreateMqttClient();

            var optionBuilder = new MqttClientOptionsBuilder()
            .WithTcpServer(_config.MQTTServer, _config.MQTTPort)
            .WithClientId(_config.ClientId);

            if (!string.IsNullOrWhiteSpace(_config.UserName) && !string.IsNullOrWhiteSpace(_config.Password))
                optionBuilder = optionBuilder.WithCredentials(_config.UserName, _config.Password);

            _mqttClientOptions = optionBuilder.Build();

            //await _mqttClient.ConnectAsync(_mqttClientOptions, CancellationToken.None);

            _mqttClientSubscribeOptions = _mqttFactory.CreateSubscribeOptionsBuilder()
                                       .WithTopicFilter(
                                           f =>
                                           {
                                               f.WithTopic($"T_{_config.ClientId}");
                                           })
                                        .Build();

            _mqttClient.ApplicationMessageReceivedAsync += MqttClient_ApplicationMessageReceivedAsync;
        }

        private async Task MqttClient_ApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs arg)
        {
            var arraySegment = arg.ApplicationMessage.PayloadSegment;
            string pluginId = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count);

            try
            {
                PluginLoader.ExecutePlugin(pluginId);
            }
            catch (Exception) { }

            await Task.CompletedTask;
        }


        private void InitializeConfig()
        {
            var config = EasyConf.Read<Config>();
            if (string.IsNullOrWhiteSpace(config.ClientId))
            {
                config.ClientId = Guid.NewGuid().ToString("N").ToUpper();
            }

            EasyConf.Write(config);
        }

        private void ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem toolStripMenuItem = sender as ToolStripMenuItem;
            var tag = toolStripMenuItem.Tag as string;
            switch (tag)
            {
                case "sys": new FrmSysConfig().ShowDialog(); break;
                case "plugin": new FrmPlugins().ShowDialog(); break;
                case "about": new FrmAbout().ShowDialog(); break;
                case "reload":
                    PluginLoader.UnloadAll();
                    PluginLoader.LoadPlugins(App.PluginDirectoryPath);
                    lblPluginCount.Text = PluginLoader.Plugins.Count().ToString();
                    MessageBox.Show($"重新加载完成");
                    break;
            }
        }

        private async void timerReConnect_Tick(object sender, EventArgs e)
        {
            if (!_mqttClient.IsConnected)
            {
                try
                {
                    await _mqttClient.ConnectAsync(_mqttClientOptions, CancellationToken.None);
                    await _mqttClient.SubscribeAsync(_mqttClientSubscribeOptions, CancellationToken.None);
                }
                catch { }
            }

            lblConnected.Text = _mqttClient.IsConnected == true ? "已连接" : "连接中";
            lblConnected.BackColor = _mqttClient.IsConnected == true ? Color.MediumSeaGreen : Color.Gold;
        }

        private void lblPlugin_Click(object sender, EventArgs e)
        {
            new FrmPlugins().ShowDialog();
        }

        private void lblClientId_Click(object sender, EventArgs e)
        {
            if (lblClientId.Text == _firstShowClientId)
                lblClientId.Text = _config.ClientId;
            else
                lblClientId.Text = _firstShowClientId;
        }

        private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
                this.WindowState = FormWindowState.Normal;

            ShowForm();
        }

        private void ShowMainToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowForm();
        }

        private void ExitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            System.Environment.Exit(0);
        }

        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = true;
            HideForm();
        }

        private void HideForm()
        {
            this.Hide();
        }

        private void ShowForm()
        {
            this.Show();
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == NativeMethods.WM_ACTIVATE_PREVIOUS_INSTANCE)
            {
                if (WindowState == FormWindowState.Minimized)
                {
                    WindowState = FormWindowState.Normal;
                }
                ShowForm();
                Activate();
            }
            base.WndProc(ref m);
        }
    }
}
